#ifndef SKYROAD_OPTIONS_H_
#define SKYROAD_OPTIONS_H_

#include <skyroad/cross_platform/console_ctrl.h>
#include <string>
#include <map>
#include <vector>
#include <algorithm>
#include <iostream>
#include <boost/thread.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>


static std::string& app_path()
{
    static std::string app_path_;

    if (app_path_ == "") 
    {
        char buffer[1024];
        get_app_path(buffer,1024);
        std::string filename(buffer);
        std::string::reverse_iterator rit = std::find(filename.rbegin(), filename.rend(), '\\');
        std::string::iterator it = rit.base();
        filename.erase(--it, filename.end());
        app_path_ = filename;
    }
    return app_path_;
}

template <typename T>
T option_value_cast(const std::string& s, const T& def);

template <>
inline int option_value_cast(const std::string& s, const int& def) 
{
    if (s.empty())
    {
        return def;
    }
    return atoi(s.c_str());
}

template <>
inline float option_value_cast(const std::string& s, const float& def) 
{
    if (s.empty())
    {
        return def;
    }
    return (float) atof(s.c_str());
}

template <>
inline double option_value_cast(const std::string& s, const double& def) 
{
    if (s.empty())
    {
        return def;
    }
    return (double) atof(s.c_str());
}

template <>
inline bool option_value_cast(const std::string& s, const bool& def) 
{
    if (s.empty())
    {
        return def;
    }
    return s == "1";
}

template <>
inline std::string option_value_cast(const std::string& s, const std::string& def) 
{
    if (s.empty())
    {
        return def;
    }
    return s;
}

template <>
inline std::vector<std::string> option_value_cast(const std::string& s, const std::vector<std::string>& def) 
{
    if (s.empty())
    {
        return def;
    }
    std::vector<std::string> result;
    boost::char_separator<char> sep(",");
    boost::tokenizer<boost::char_separator<char> > tokens(s, sep);
    std::copy(tokens.begin(), tokens.end(), std::back_inserter(result));
    return result;
}

class option_value
{
public:
    option_value(const std::string& value) : m_value(value) 
    {
    }

    option_value() 
    {
    }
public:
    template <typename T> 
    T as(const T& def) 
    {
        return option_value_cast<T>(m_value, def);
    }

private:
    std::string m_value;
};


static option_value get_option(const char*section, const char *key) 
{
    char buf[1024]={0};
    std::string path = app_path() + "\\system_config.ini";
    get_ini_profile_str(section,key,buf,1024,path.c_str());
    return option_value(buf);
}

#endif
